'''
装饰器
'''
import time
#例4-19电商客服
'''
#模拟客服与客户对话
def contact():
    q = input("问：")
    print("答：亲~ 对不起，暂时无法解答'{}'这个问题！".format(q))
#欢迎话术
print("亲~，请问有什么可以帮助您的吗？")

#联系客服
contact()

#结束话术
print("亲~，请为我的服务打分！")
print("1 非常满意，2 满意，3 一般，4 差")
score = input("请输入您的打分：")
print("感谢您的评价！谢谢！")
'''

#例4-20使用闭包改造电商客服
#机器人在调用被装饰函数func前后打印标准话术

def robot(func):
    def say():
        print("亲~，请问有什么可以帮助您的吗？")
        #被装饰函数func
        func()
        print("亲~，请为我的服务打分！")
        print("1 非常满意，2 满意，3 一般，4 差")
        score = input("请输入您的打分：")
        print("感谢您的评价！谢谢！")
    return say

# def contact():
#     q = input("问：")
#     print("答：亲~ 对不起，暂时无法解答'{}'这个问题！".format(q))
#
# func_closure = robot(contact)
# func_closure()

#例4-21使用装饰器改造电商客服

@robot
def contact():
    q = input("问：")
    print("正在输入.....")
    print("答：亲~ 对不起，暂时无法解答'{}'这个问题！".format(q))

#调用函数
#contact()


#例4-22 装饰器装饰带参函数

#计算程序执行耗时
def time_counter(func):
     #在内层函数counter中设置与被装饰函数相同的参数
    def counter(x,y):
        start_time = time.time()
        print("start_time:",start_time)
        func(x,y)
        end_time = time.time()
        print("end_time:", end_time)
        print("run times:", end_time - start_time)
    return counter
#求两个数字的和
@time_counter
def sum(x,y):
    time.sleep(2)
    print("{} + {} = {}".format(x,y,x+y))

#sum(10,20)


#例4-23 给装饰器的内层函数添加不定长参数，使得装饰器可以装饰更多函数

#计算程序执行耗时
def time_counter(func):
    #使用不定长参数接收任意个数的参数传入
    def counter(*args):
        start_time = time.time()
        print("start_time:",start_time)
        func(*args)
        end_time = time.time()
        print("end_time:", end_time)
        print("run times:", end_time - start_time)
    return counter
#求两个数字的和
@time_counter
def sum(x,y):
    time.sleep(2)
    print("{} + {} = {}".format(x,y,x+y))

#求三个数字的乘积
@time_counter
def multiplied(x,y,z):
    time.sleep(2)
    print("{} * {} * {} = {}".format(x,y,z,x*y*z))

# sum(10,20)
# multiplied(2,3,4)


#例4-24 带参装饰器的使用
#存储学生考试成绩
stuscores = {}
def if_admin(admin):
    def check(func):
        def inner(t_name,s_name,score):
            print("正在进行权限检查...")
            if t_name != admin:
                #如果不是管理员，则抛出异常
                raise Exception("权限不够！禁止操作！")
            func(t_name,s_name,score)
            print("操作成功！")
        return inner
    return check

#添加学生考试成绩
@if_admin("admin")
def add_stu_score(t_name,s_name,score):
    stuscores[s_name] = score

#修改学生考试成绩
@if_admin("admin")
def update_stu_score(t_name,s_name,score):
    stuscores[s_name] = score

add_stu_score("admin","Tom",100)
print(stuscores)
update_stu_score("admin","Tom",95)
print(stuscores)
add_stu_score("derek","David",97)
print(stuscores)